package api.server;

import com.ycy.lucene.index.IndexReadDemo;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.*;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.wltea.analyzer.lucene.IKAnalyzer6x;

import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;

@Slf4j
public class IndexDemo {

  //源文件
  public static String indexPath;

  //索引位置
  static Directory directory = null;

  static IndexWriter indexWriter = null;

  static {
    // 获取用户目录
    String userDirectory = System.getProperty("user.home");
    // 打印用户目录
    log.info("用户目录: " + userDirectory);
    // 获取文件分隔符
    String fileSeparator = System.getProperty("file.separator");
    // 打印文件分隔符
    log.info("文件分隔符: " + fileSeparator);


    indexPath = userDirectory + fileSeparator + "Desktop" + fileSeparator + "linshilucenedata" + fileSeparator + "ix2";
    log.info("数据源目录 -> {} 索引生成目录 -> {}", "pathname", indexPath);

    System.out.println("start create index ... ");
    try {
      Path path = Paths.get(indexPath);
      //FSDirectory.open(...)  同一时刻只能打开一次
      directory = FSDirectory.open(path);

      Analyzer standardAnalyzer = new IKAnalyzer6x();

      IndexWriterConfig indexWriterConfig = new IndexWriterConfig(standardAnalyzer);
      indexWriterConfig.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
      // IndexWriter 实例只能同时有一个
      indexWriter = new IndexWriter(directory, indexWriterConfig);

    } catch (IOException e) {
      e.printStackTrace();
    }

  }

  // 创建文档
  public static void createDocument() {

    try {

      int i = 0;
      for (int j = 0; j < 2; j++) {

        Document doc = new Document();
//      TextField nameField = new TextField("name", "Elk Mills Park塞西尔县Elk Mills ParkElk Mills Park美国马里兰州", Field.Store.YES);
//        FieldType FieldType = new FieldType();
//        FieldType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
//        FieldType.setTokenized(true);
//        Field nameField = new Field("name", s, FieldType);

        Field id = new TextField("id", "100", Field.Store.YES);
        SimpleDateFormat simpleDateFormat = new
                SimpleDateFormat("yyyy-MM-dd HH:mm:ss.sss");
        Field name = new StoredField("name", "hello world"+ simpleDateFormat.format(new Date()));
        doc.add(id);
        doc.add(name);

        System.out.println(++i);
        // 重要可以支持多并发
        indexWriter.addDocument(doc);
      }

      System.out.println("end create index ... ");
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public static void flush() {
    try {

      //0618 flush 会使查询生效吗?
      indexWriter.flush();

    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public static void commit() {
    try {
      indexWriter.commit();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public static void close(){
    try {
      indexWriter.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  static volatile IndexSearcher indexSearcher = null;

  // 查询索引
  public static IndexSearcher getIndexSearch() {
    if (indexSearcher == null)
      synchronized (IndexReadDemo.class) {
        if (indexSearcher == null) {
          DirectoryReader indexReader = null;
          try {


            indexReader = DirectoryReader.open(directory);
          } catch (IOException e) {
            throw new RuntimeException(e);
          }
          indexSearcher = new IndexSearcher(indexReader);
        }
      }
    return indexSearcher;
  }

  public static String reOpenIfChanged() {
    synchronized (IndexReadDemo.class) {
      if (indexSearcher != null) {
        DirectoryReader indexReader = (DirectoryReader) indexSearcher.getIndexReader();
        DirectoryReader newReader = null;
        try {
          // 重要:如果索引发生更新和删除,必须重新生成IndexSearch才能查询到文更新和删除后的文档变化。
          // 调用 flush 也不会触发更新
          newReader = DirectoryReader.openIfChanged(indexReader);

          if (newReader != null) {
            indexReader.close();
            IndexSearcher searcher = new IndexSearcher(newReader);
            indexSearcher = searcher;
            return newReader.toString();
          }

        } catch (IOException e) {
          throw new RuntimeException(e);
        }
      }
    }
    return "indexSearch 不需要更新";
  }

  public static String search() {
    //查询第一个文档
    TermQuery termQuery = new TermQuery(new Term("id", "100"));
    StringBuilder stringBuilder = new StringBuilder();
    TopDocs topDocs = null;
    try {
      IndexSearcher indexSearch = getIndexSearch();
      topDocs = indexSearch.search(termQuery, 1000);
      if (topDocs == null || topDocs.scoreDocs == null) {
        return stringBuilder.toString();
      }
      for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        Document doc = indexSearch.doc(scoreDoc.doc);
        stringBuilder.append("id:" + doc.get("id") + "," + "name:" + doc.get("name"));
        stringBuilder.append("\n");
      }
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
    return stringBuilder.toString();
  }


}
